package com.dms.modules.cart.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.dms.common.api.ApiResponse;
import com.dms.common.exception.BusinessException;
// import com.dms.common.utils.SecurityUtils;
import com.dms.common.security.SecurityUtils;
import com.dms.modules.cart.dto.CartItemDTO;
import com.dms.modules.cart.entity.CartItem;
import com.dms.modules.cart.service.CartService;
import com.dms.modules.merchant.service.MerchantService;
import com.dms.modules.merchant.entity.Merchant;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@RestController
@RequestMapping("/api/v1/cart")
@Api(tags = "购物车接口")
@Validated
@PreAuthorize("hasRole('USER')")
@RequiredArgsConstructor
public class CartController {

    private final CartService cartService;
    private final MerchantService merchantService;

    /**
     * 获取当前登录用户ID
     */
    private Long getCurrentUserId() {
        return SecurityUtils.getCurrentUserId();
    }

    @GetMapping("/list")
    @ApiOperation("获取购物车列表")
    public ApiResponse<List<CartItemDTO>> getCartList() {
        try {
            Long userId = getCurrentUserId();
            List<CartItemDTO> cartItems = cartService.getUserCartItems(userId);
            
            // 获取所有商家ID
            Set<Long> merchantIds = cartItems.stream()
                    .map(CartItemDTO::getMerchantId)
                    .collect(Collectors.toSet());
            
            // 只在有商家ID时才查询商家信息
            if (!merchantIds.isEmpty()) {
                // 批量查询商家信息
                Map<Long, Merchant> merchantMap = merchantService.listByIds(merchantIds)
                        .stream()
                        .collect(Collectors.toMap(Merchant::getId, merchant -> merchant));
                
                // 设置商家名称
                cartItems.forEach(item -> {
                    Merchant merchant = merchantMap.get(item.getMerchantId());
                    if (merchant != null) {
                        item.setMerchantName(merchant.getShopName());
                    }
                });
            }
            
            return ApiResponse.success(cartItems);
        } catch (BusinessException e) {
            log.warn("获取购物车列表失败: {}", e.getMessage());
            return ApiResponse.error(e.getMessage());
        } catch (Exception e) {
            log.error("获取购物车列表失败", e);
            return ApiResponse.error("获取购物车列表失败");
        }
    }

    //添加商品到购物车
    @PostMapping
    @ApiOperation("添加商品到购物车")
    public ApiResponse<Void> addToCart(@RequestBody @Valid CartItemDTO cartItemDTO) {
        try {
            Long userId = getCurrentUserId();
            cartService.addToCart(userId, cartItemDTO.getProductId(), cartItemDTO.getSkuId(), cartItemDTO.getQuantity());
            return ApiResponse.success();
        } catch (BusinessException e) {
            log.warn("添加商品到购物车失败: {}", e.getMessage());
            return ApiResponse.error(e.getMessage());
        } catch (Exception e) {
            log.error("添加商品到购物车失败", e);
            return ApiResponse.error("添加商品到购物车失败");
        }
    }

    @PutMapping("/{id}/quantity/{quantity}")
    @ApiOperation("更新购物车商品数量")
    public ApiResponse<Void> updateQuantity(
            @PathVariable @NotNull(message = "购物车项ID不能为空") Long id,
            @PathVariable @Min(value = 1, message = "数量不能小于1") Integer quantity) {
        try {
            Long userId = getCurrentUserId();
            cartService.updateQuantity(userId, id, quantity);
            return ApiResponse.success();
        } catch (BusinessException e) {
            log.warn("更新购物车商品数量失败: {}", e.getMessage());
            return ApiResponse.error(e.getMessage());
        } catch (Exception e) {
            log.error("更新购物车商品数量失败", e);
            return ApiResponse.error("更新购物车商品数量失败");
        }
    }

    @DeleteMapping("/{id}")
    @ApiOperation("移除购物车商品")
    public ApiResponse<Void> removeFromCart(@PathVariable @NotNull(message = "购物车项ID不能为空") Long id) {
        try {
            Long userId = getCurrentUserId();
            cartService.removeFromCart(userId, Collections.singletonList(id));
            return ApiResponse.success();
        } catch (BusinessException e) {
            log.warn("移除购物车商品失败: {}", e.getMessage());
            return ApiResponse.error(e.getMessage());
        } catch (Exception e) {
            log.error("移除购物车商品失败", e);
            return ApiResponse.error("移除购物车商品失败");
        }
    }

    @DeleteMapping("/batch")
    @ApiOperation("批量移除购物车商品")
    public ApiResponse<Void> batchRemoveFromCart(@RequestBody @NotEmpty(message = "商品ID列表不能为空") List<Long> ids) {
        try {
            Long userId = getCurrentUserId();
            cartService.removeFromCart(userId, ids);
            return ApiResponse.success();
        } catch (BusinessException e) {
            log.warn("批量移除购物车商品失败: {}", e.getMessage());
            return ApiResponse.error(e.getMessage());
        } catch (Exception e) {
            log.error("批量移除购物车商品失败: ids={}", ids, e);
            return ApiResponse.error("批量移除购物车商品失败");
        }
    }

    @DeleteMapping("/clear")
    @ApiOperation("清空购物车")
    public ApiResponse<Void> clearCart() {
        try {
            Long userId = getCurrentUserId();
            cartService.clearCart(userId);
            return ApiResponse.success();
        } catch (BusinessException e) {
            log.warn("清空购物车失败: {}", e.getMessage());
            return ApiResponse.error(e.getMessage());
        } catch (Exception e) {
            log.error("清空购物车失败", e);
            return ApiResponse.error("清空购物车失败");
        }
    }

    @GetMapping("/by-merchant")
    @ApiOperation("获取按商家分组的购物车列表")
    public ApiResponse<Page<Map<Long, List<CartItemDTO>>>> getCartItemsByMerchant(
            @RequestParam(defaultValue = "1") @Min(value = 1, message = "页码必须大于0") Integer pageNum,
            @RequestParam(defaultValue = "10") @Min(value = 1, message = "每页条数必须大于0") Integer pageSize) {
        try {
            Long userId = getCurrentUserId();
            List<CartItemDTO> cartItems = cartService.getUserCartItems(userId);
            
            // 获取所有商家ID
            Set<Long> merchantIds = cartItems.stream()
                    .map(CartItemDTO::getMerchantId)
                    .collect(Collectors.toSet());
            
            // 批量查询商家信息
            Map<Long, Merchant> merchantMap = merchantService.listByIds(merchantIds)
                    .stream()
                    .collect(Collectors.toMap(Merchant::getId, merchant -> merchant));
            
            // 设置商家名称
            cartItems.forEach(item -> {
                Merchant merchant = merchantMap.get(item.getMerchantId());
                if (merchant != null) {
                    item.setMerchantName(merchant.getShopName());
                }
            });
            
            // 按商家分组
            Map<Long, List<CartItemDTO>> cartItemsByMerchant = cartItems.stream()
                    .collect(Collectors.groupingBy(CartItemDTO::getMerchantId));
            
            // 将Map转换为List并按商家ID排序
            List<Map.Entry<Long, List<CartItemDTO>>> merchantList = new ArrayList<>(cartItemsByMerchant.entrySet());
            merchantList.sort(Map.Entry.comparingByKey());
            
            // 计算分页
            int startIndex = (pageNum - 1) * pageSize;
            int endIndex = Math.min(startIndex + pageSize, merchantList.size());
            
            // 创建分页结果
            Page<Map<Long, List<CartItemDTO>>> page = new Page<>(pageNum, pageSize);
            page.setTotal(merchantList.size());
            
            // 获取当前页的数据
            Map<Long, List<CartItemDTO>> currentPageData = new LinkedHashMap<>();
            for (int i = startIndex; i < endIndex; i++) {
                Map.Entry<Long, List<CartItemDTO>> entry = merchantList.get(i);
                currentPageData.put(entry.getKey(), entry.getValue());
            }
            
            page.setRecords(Collections.singletonList(currentPageData));
            return ApiResponse.success(page);
        } catch (BusinessException e) {
            log.warn("获取按商家分组的购物车列表失败: {}", e.getMessage());
            return ApiResponse.error(e.getMessage());
        } catch (Exception e) {
            log.error("获取按商家分组的购物车列表失败", e);
            return ApiResponse.error("获取按商家分组的购物车列表失败");
        }
    }
} 